//
//  MGCache.m
//  MGPublic
//
//  Created by lhongl on 2025/10/27.
//

#import "MGCache.h"
#import <PINCache/PINCache.h>
#import "MGEmpty.h"
static NSString * const _mg_cache_name = @"mg_yy_cache";
@interface MGCache ()

///
@property (nonatomic, strong) NSMutableDictionary<NSString *,PINCache *> *cachesManage;

/// 默认
@property (nonatomic, strong) PINCache *cache;

@end
@implementation MGCache

+ (instancetype)shareCache {
    static dispatch_once_t onceToken;
    static MGCache * _cacheManage;
    dispatch_once(&onceToken, ^{
        _cacheManage = [[MGCache alloc] init];
        _cacheManage.cachesManage = [NSMutableDictionary dictionary];
        _cacheManage.cache = [PINCache sharedCache];
    });
    return _cacheManage;
}

#pragma mark 初始化对象
+ (PINCache *)initYYCacheWithCacheName:(NSString *_Nullable)cacheName{
    MGCache *shareCache = [MGCache shareCache];
    if (MGEmpty.isEmpty(cacheName)) {
        return shareCache.cache;
    }
    if (shareCache.cachesManage[cacheName]) {
        return shareCache.cachesManage[cacheName];
    }
    PINCache *cache = [[PINCache alloc] initWithName:cacheName];
    [shareCache.cachesManage setObject:cache forKey:cacheName];
    return cache;
}

#pragma mark - 包含
/// 包含
/// - Parameter key: key
+ (BOOL)containsObjectForKey:(NSString *)key {
    return [self containsObjectForKey:key withCacheName:nil];
}

/// 包含
/// - Parameters:
///   - key: key
///   - cacheName: 缓存name
+ (BOOL)containsObjectForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    return [cache containsObjectForKey:key];
}

/// 包含异步
/// - Parameters:
///   - key: key
///   - block: 回调
+ (void)containsObjectAsyncForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block {
    [self containsObjectAsyncForKey:key withCacheName:nil withBlock:block];
}

/// 包含异步
/// - Parameters:
///   - key: key
///   - cacheName: 缓存name
///   - block: 回调
+ (void)containsObjectAsyncForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName withBlock:(nullable void(^)(NSString *key, BOOL contains))block {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache containsObjectForKeyAsync:key completion:^(BOOL containsObject) {
        if (block) {
          block(key, containsObject);
        }
    }];
}

#pragma mark - 获取对象
/// 获取
/// - Parameter key: key
+ (nullable id)objectForKey:(NSString *)key {
    return [self objectForKey:key withCacheName:nil];
}

/// 获取
/// - Parameter key: key
/// - cacheName: 缓存name
+ (nullable id)objectForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    return  [cache objectForKey:key];
}

/// 获取异步
/// - Parameters:
///   - key: 对象
///   - block: 回调
+ (void)objectAsyncForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id _Nullable object))block {
    [self objectAsyncForKey:key withCacheName:nil withBlock:block];
}

/// 获取异步
/// - Parameters:
///   - key: 对象
///   - cacheName: 缓存name
///   - block: 回调
+ (void)objectAsyncForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName withBlock:(nullable void(^)(NSString *key, id _Nullable object))block {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache objectForKeyAsync:key completion:^(__kindof id<PINCaching>  _Nonnull cache, NSString * _Nonnull key, id  _Nullable object) {
        if (block) {
            block(key, object);
        }
    }];
}

#pragma mark - 存储
/// 存储
/// - Parameters:
///   - object: 对象
///   - key: key
+ (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {
    [self setObject:object forKey:key withCacheName:nil];
}

/// 存储
/// - Parameters:
///   - object: 对象
///   - key: key
///   - cacheName: 缓存name
+ (void)setObject:(id<NSCoding>)object forKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache setObject:object forKey:key];
}

/// 存储异步
/// - Parameters:
///   - object: 对象
///   - key: jkey
///   - block: 回调
+ (void)setObjectAsnyc:(id<NSCoding>)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block {
    [self setObjectAsnyc:object forKey:key withCacheName:nil withBlock:block];
}

/// 存储异步
/// - Parameters:
///   - object: 对象
///   - key: key
///   - cacheName: 缓存name
///   - block: 回调
+ (void)setObjectAsnyc:(id<NSCoding>)object forKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName withBlock:(nullable void(^)(void))block {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache setObjectAsync:object forKey:key completion:^(__kindof id<PINCaching>  _Nonnull cache, NSString * _Nonnull key, id  _Nullable object) {
        if (block) {
            block();
        }
    }];
}

#pragma mark - 删除
/// 删除
/// - Parameter key: key
+ (void)removeObjectForKey:(NSString *)key {
    [self removeObjectForKey:key withCacheName:nil];
}

/// 删除
/// - Parameter key: key
/// - cacheName: cacheName
+ (void)removeObjectForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache removeObjectForKey:key];
}

/// 删除异步
/// - Parameters:
///   - key: key
///   - block: 回调
+ (void)removeObjectAsnycForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block {
    [self removeObjectAsnycForKey:key withCacheName:nil withBlock:block];
}

/// 删除异步
/// - Parameters:
///   - key: key
///   - cacheName cacheName
///   - block: 回调
+ (void)removeObjectAsnycForKey:(NSString *)key withCacheName:(NSString *_Nullable)cacheName withBlock:(nullable void(^)(NSString *key))block {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache removeObjectForKeyAsync:key completion:^(__kindof id<PINCaching>  _Nonnull cache, NSString * _Nonnull key, id  _Nullable object) {
        if (block) {
            block(key);
        }
    }];
}

/// 删除所有
+ (void)removeAllObjects {
    [self removeAllObjectsWithCacheName:nil];
}

/// 删除所有
/// - Parameters:
/// - cacheName cacheName
+ (void)removeAllObjectsWithCacheName:(NSString *_Nullable)cacheName {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache removeAllObjects];
}

/// 删除所有异步
/// - Parameter block: 回调
+ (void)removeAllObjectsAsnycWithBlock:(void(^)(void))block {
    [self removeAllObjectsAsnycWithCacheName:nil withBlock:block];
}

/// 删除所有异步
/// - Parameters:
///   - cacheName: cacheName
///   - block: 回调
+ (void)removeAllObjectsAsnycWithCacheName:(NSString *_Nullable)cacheName withBlock:(void(^)(void))block {
    PINCache *cache = [self initYYCacheWithCacheName:cacheName];
    [cache removeAllObjectsAsync:^(__kindof id<PINCaching>  _Nonnull cache) {
        if (block) {
            block();
        }
    }];
}


/// 删除所有Cache缓存异步
/// - Parameter block: 回调
+ (void)removeAllCachesAsnycWithBlock:(void(^)(void))block {
    MGCache *shareCache = [MGCache shareCache];
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        [shareCache.cache removeAllObjectsAsync:^(__kindof id<PINCaching>  _Nonnull cache) {
            dispatch_group_leave(group);
        }];
    });
    if (shareCache.cachesManage.count != 0) {
        [shareCache.cachesManage enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, PINCache * _Nonnull obj, BOOL * _Nonnull stop) {
            dispatch_group_enter(group);
            dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
                [obj removeAllObjectsAsync:^(__kindof id<PINCaching>  _Nonnull cache) {
                    dispatch_group_leave(group);
                }];
            });
        }];
    }
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        if (block) {
            block();
        }
    });
}

@end
